#include <stdarg.h>
#include <string.h>
#include <stdio.h>

#include <sched.h>

extern struct mtd_info mtd;
extern struct file_list_tree_t *ptree;

int pipe_mode = 0;
FILE *file_in, *file_out;

struct Command {
	const char *name;
	const char *desc;
	int (*func)(int argc, char **argv);
};

static int inter_help(int argc, char **argv);
static int inter_exit(int argc, char **argv);
static int inter_recover_all(int argc, char **argv);

static struct Command commands[] = {
	{ "help", "Display this list of commands", inter_help },
	{ "exit", "Exit yaffs2recover", inter_exit},
	{ "recoverall", "Recover all files in the image", inter_recover_all},
};

#define NCOMMANDS (sizeof(commands)/sizeof(struct Command))
#define WHITESPACE "\t\r\n"
#define MAXARGS 16
#define MAXBUF 1024

static void 
iprintf(const char *fmt, ...)
{
	va_list args;
	va_start(args, fmt);
	vfprintf(file_out, fmt, args);
	va_end(args);
}

static void
prompt()
{
	pipe_mode ? 0 : iprintf("yaffs2recover> ");
}

static int
inter_exit(int argc, char **argv)
{
	return -1;
}

static int
inter_recover_all(int argc, char **argv)
{
	iprintf("Recovering...");
	file_recover_iterate_tree(&mtd, ptree);
	iprintf("Done!\n");
	return 0;
}

static int
inter_help(int argc, char **argv)
{
	int i;
	for (i = 0; i < NCOMMANDS; i++)
		fprintf(stderr, "%s - %s\n", commands[i].name, commands[i].desc);
	return 0;
}

static int
runcmd(char *buf)
{
	int argc;
	char *argv[MAXARGS];
	int i;

	argc = 0;
	argv[argc] = 0;
	while (1) {
		// gobble whitespace
		while (*buf && strchr(WHITESPACE, *buf))
			*buf++ = 0;
		if (*buf == 0)
			break;

		// save and scan past next arg
		if (argc == MAXARGS-1) {
			fprintf(stderr, "Too many arguments (max %d)\n", MAXARGS);
			return 0;
		}
		argv[argc++] = buf;
		while (*buf && !strchr(WHITESPACE, *buf))
			buf++;
	}
	argv[argc] = 0;

	// Lookup and invoke the command
	if (argc == 0)
		return 0;
	for (i = 0; i < NCOMMANDS; i++) {
		if (strcmp(argv[0], commands[i].name) == 0)
			return commands[i].func(argc, argv);
	}
	fprintf(stderr, "\nUnknown command '%s'\n", argv[0]);
	return 0;
}




void
interactive_mode(FILE *pipe_in, FILE *pipe_out)
{
	if (!pipe_in)
		file_in = stdin;
	if (!pipe_out)
		file_out = stdout;

	if (!pipe_in && !pipe_out)
	pipe_mode = !pipe_in && !pipe_out ? 0 : 1;
	
	char buf[1024];
	
	while(1) {
		prompt();
		if (fgets(buf, MAXBUF, file_in) == 0) {
			sched_yield();
			continue;
		}
		if (strlen(buf) < 2)
			continue;

		if (runcmd(buf) < 0)
			break;
	}
	
}



